/* eslint-disable promise/param-names */
/* eslint-disable node/handle-callback-err */

let cookie = null, tid = 2

const pkg_path = `${process.cwd()}/package.json`

const rootpkg = '@zh',
  fs = require('fs'),
  FileUtil = require('../file'),
  args = process.argv.splice(2),
  os = require('os'),
  request = require(`./${os.platform()}/request`),
  version = args.find(arg => arg.startsWith('-v='))?.split('=').pop(),
  tag = args.find(arg => arg.startsWith('-t='))?.split('=').pop() || ''

async function main () {
  await login()
  const dependencies = {}, devDependencies = {}, pkg = require(pkg_path)
  Object.keys(pkg.dependencies).forEach(dependenceName => {
    if (dependenceName.startsWith(rootpkg)) {
      if (version) {
        pkg.dependencies[dependenceName] = version
      } else {
        dependencies[dependenceName] = pkg.dependencies[dependenceName]
      }
    }
  })
  await asyncUpdateVersion(pkg, dependencies)
  await asyncUpdateVersion(pkg, devDependencies)

  fs.writeFileSync(pkg_path, JSON.stringify(pkg, null, 2), 'utf8')

  if (fs.existsSync(`${process.cwd()}/node_modules`)) {
    console.info('清理 node_modules 这可能需要几分钟时间，请稍后...')
    FileUtil.deleteDir(`${process.cwd()}/node_modules`)
  }

  const lockfile = `${process.cwd()}/package-lock.json`
  if (fs.existsSync(lockfile)) {
    fs.unlinkSync(lockfile)
  }

  console.info('开始安装依赖')
}

async function login () {
  return new Promise((resolve, reject) => {
    request.post('http://nexus.zt.com.cn:38081/service/rapture/session', {
      form: {
        username: 'Y2hlbndlaQ==',
        password: 'MTExMTExMTE='
      }
    }, (error, response, body) => {
      if (response.statusCode !== 204) {
        console.error('登录失败')
        process.exit(1)
      }
      cookie = response.headers['set-cookie']?.[0]
      cookie && (cookie = cookie.split(';')[0])
      resolve()
    })
  })
}

async function asyncUpdateVersion (pkg, dependencies) {
  if (Object.keys(dependencies).length == 0) {
    return
  }
  let dependenceName = Object.keys(dependencies)[0]
  const result = await getLastedVersion(dependenceName)
  pkg.dependencies[dependenceName] = result.version
  delete dependencies[dependenceName]
  asyncUpdateVersion(pkg, dependencies)
}

function getLastedVersion (dependenceName) {
  dependenceName = dependenceName.replace('@', '').split('/')
  const body = {
    action: 'coreui_Search',
    method: 'read',
    data: [{
      page: 1,
      start: 0,
      limit: 50,
      sort: [{
        property: 'version',
        direction: 'DESC'
      }],
      filter: [{
        property: 'group.raw',
        value: dependenceName[0]
      }, {
        property: 'name.raw',
        value: dependenceName[1]
      }]
    }],
    type: 'rpc',
    tid: tid++
  }
  tag && body.data[0].filter.push({
    property: 'keyword',
    value: tag
  })
  return new Promise((reslove, reject) => {
    request.post('http://nexus.zt.com.cn:38081/service/extdirect', {
      headers: {
        'content-type': 'application/json',
        Cookie: cookie
      },
      body: JSON.stringify(body)
    }, (error, response, body) => {
      if (response.statusCode !== 200) {
        reslove()
      }
      const results = JSON.parse(response.body).result.data
      if (results.length == 0) {
        reslove()
      } else if (tag) {
        reslove(results[0])
      } else {
        reslove(results.find(item => item.version.indexOf('-') == -1))
      }
    })
  })
}

main()